package org.richin.support.web.struts;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.*;
import org.apache.struts.config.ModuleConfig;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.struts.DelegatingActionUtils;

// Referenced classes of package org.springframework.web.struts:
//            DelegatingActionUtils

public class AutowiringRequestProcessor extends RequestProcessor {
	private WebApplicationContext webApplicationContext;
	private int autowireMode;
	private boolean dependencyCheck;

	public AutowiringRequestProcessor() {
		autowireMode = 0;
		dependencyCheck = false;
	}

	public void init(ActionServlet actionServlet, ModuleConfig moduleConfig) throws ServletException {
		super.init(actionServlet, moduleConfig);
		
		if (actionServlet != null) {
			webApplicationContext = initWebApplicationContext(actionServlet, moduleConfig);
			autowireMode = initAutowireMode(actionServlet, moduleConfig);
			dependencyCheck = initDependencyCheck(actionServlet, moduleConfig);
		}
	}

	protected WebApplicationContext initWebApplicationContext(ActionServlet actionServlet, ModuleConfig moduleConfig)
			throws IllegalStateException {
		WebApplicationContext wac = DelegatingActionUtils
				.findRequiredWebApplicationContext(actionServlet, moduleConfig);
		if (wac instanceof ConfigurableApplicationContext)
			((ConfigurableApplicationContext) wac).getBeanFactory().ignoreDependencyType(
					org.apache.struts.action.ActionServlet.class);
		return wac;
	}

	protected int initAutowireMode(ActionServlet actionServlet, ModuleConfig moduleConfig) {
		String autowire = actionServlet.getInitParameter("spring.autowire");
		if (autowire != null) {
			if ("byName".equals(autowire))
				return 1;
			if (!"byType".equals(autowire))
				throw new IllegalArgumentException("ActionServlet 'autowire' parameter must be 'byName' or 'byType'");
		}
		return 2;
		
	}

	protected boolean initDependencyCheck(ActionServlet actionServlet, ModuleConfig moduleConfig) {
		return DelegatingActionUtils.getDependencyCheck(actionServlet);
	}

	protected final WebApplicationContext getWebApplicationContext() {
		return webApplicationContext;
	}

	protected final int getAutowireMode() {
		return autowireMode;
	}

	protected final boolean getDependencyCheck() {
		return dependencyCheck;
	}

	protected Action processActionCreate(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping)
			throws IOException {
		Action action = super.processActionCreate(request, response, mapping);
		
		getWebApplicationContext().getAutowireCapableBeanFactory().autowireBeanProperties(action, getAutowireMode(),
				getDependencyCheck());
		return action;
	}

}